package com.ansion.commonchat.db;

import android.content.Context;
import android.os.Build;

import com.ansion.basedb.dao.DaoLoadHelper;
import com.ansion.basedb.dao.helper.ContactsHelper;
import com.ansion.basedb.dao.helper.GroupHelper;
import com.ansion.basedb.dao.helper.UserHelper;
import com.ansion.basedb.dao.model.ContactsModel;
import com.ansion.basedb.dao.model.GroupModel;
import com.ansion.basedb.dao.model.UserModel;
import com.ansion.basedb.database.DatabaseManager;
import com.ansion.basedb.database.IDatabaseManager;
import com.ansion.basedb.storage.StorageSdk;
import com.ansion.log.VLog;
import com.ansion.utils.ResourceUtils;

import java.io.File;
import java.util.ArrayList;
import java.util.List;


public class CocoDBFactory {

    /**
     * Edit this version when table columns changed.
     */
    private static final int VERSION_CODE_DB = 1012;
    public static boolean loaded;

    static {
        if (isLoadCiptherDB()) {
            try {
                System.loadLibrary("sqlcipher");
//                SQLiteDatabase.loadLibs(BaseApplication.getContext());
                loaded = true;
            } catch (Throwable t) {
                loaded = false;
            }
        }
        DaoLoadHelper.sqlcipherEnable = loaded;
        VLog.i("TAG_STORAGE", "sqlcipher jni load finish,enable:%b", loaded);
    }

    private static final String TAG = "CocoDBFactory";
    private static CocoDBFactory instance;
    private volatile IDatabaseManager cocoMainDB;


    private long userId_ = 0;

    private CocoDBFactory() {
    }

    public synchronized static CocoDBFactory getInstance() {
        if (null == instance) {
            synchronized (CocoDBFactory.class) {
                if (null == instance) {
                    instance = new CocoDBFactory();
                }
            }
        }
        return instance;
    }

    public boolean initDB(long userId) {
        synchronized (this) {
            if (null != cocoMainDB && cocoMainDB.isInited()) {
                if (userId == userId_) {
                    return true;
                }
                this._unInitDB();
                VLog.e("VLog", "BUG,initDB userId is not same,newUserId="
                        + userId + ",oldUserId=" + userId_);
            }
            String trackKey = "APP_START";
            VLog.stopD(trackKey, "%s init db inner start", trackKey);
            userId_ = userId;

            List<Class<?>> models = new ArrayList<Class<?>>();
            models.add(UserModel.class);
            models.add(GroupModel.class);
            models.add(ContactsModel.class);
            Context context = ResourceUtils.getContext();
            String dbName = String.valueOf(userId) + "_coco.db";
            File dbFile = context.getDatabasePath(dbName);
//            if (!loaded || (null != dbFile && dbFile.exists())) {
//                cocoMainDB = DatabaseManager.newInstance();
//                cocoMainDB.initDataBase(context, dbName, VERSION_CODE_DB, models, SqlTableManager.getTables(false));
//                UsageHelper.updateDatabaseType(BConstant.DB.TYPE_NON_ENCRYPTED);
//            } else {
//                try {
//                    dbName = MD5Util.md5(String.valueOf(userId)) + "_coco_n.db";
//                    cocoMainDB = SqlciptherDatabaseManager.getInstance();
//                    cocoMainDB.initDataBase(context, dbName, VERSION_CODE_DB, models, SqlTableManager.getTables(true));
//                    UsageHelper.updateDatabaseType(BConstant.DB.TYPE_ENCRYPTED);
//                } catch (Throwable e) {
//                    dbName = String.valueOf(userId) + "_coco.db";
//                    cocoMainDB = DatabaseManager.newInstance();
//
//                    cocoMainDB.initDataBase(context, dbName, VERSION_CODE_DB, models, SqlTableManager.getTables(false));
//                    UsageHelper.updateDatabaseType(BConstant.DB.TYPE_NON_ENCRYPTED);
//                }
//            }
            dbName = String.valueOf(userId) + "_coco.db";
            cocoMainDB = DatabaseManager.newInstance();

            cocoMainDB.initDataBase(context, dbName, VERSION_CODE_DB, models, SqlTableManager.getTables(false));
//            UsageHelper.updateDatabaseType(BConstant.DB.TYPE_NON_ENCRYPTED);
            VLog.stopD(trackKey, "%s init db inner 3", trackKey);
//            if (notificationDao == null) {
//                if (CommonPreferenceUtils.getInstance().useNewNotifycationDB()) {
//                    notificationDao = new NotificationDaoImplV2();
//                } else {
//                    notificationDao = new NotificationDaoImpl();
//                }
//            }
            VLog.stopD(trackKey, "%s init db inner 4", trackKey);

            StorageSdk.initDataBase(cocoMainDB);
        }

        return true;
    }

    private static boolean isLoadCiptherDB() {
        if ("OPPO".equals(Build.BRAND) && "A37f".equals(Build.DEVICE)) {
            return false;
        }

        return true;
    }

    public void unInitDB() {
        _unInitDB();
        instance = null;
    }

    private void _unInitDB() {
        synchronized (CocoDBFactory.class) {
            if (null == cocoMainDB) {
                return;
            }

            unInitDaos();
            cocoMainDB.setInited(false);
            cocoMainDB.recycle();
            StorageSdk.clearDB();
            cocoMainDB = null;
            userId_ = 0;
        }
    }

    public void syncPreloadData() {
        if (userId_ == 0)
            return;
        final String trackKey = "APP_START";
        VLog.stopD(trackKey, "%s preload start ", trackKey);

        try {
            UserHelper.getUserDBDao().loadAll();
            VLog.stopD(trackKey, "%s user preload end", trackKey);
            GroupHelper.getGroupDBDao().loadAllGroups();
            VLog.stopD(trackKey, "%s group preload end", trackKey);
            ContactsHelper.getContactsDao().loadAll(true);
            VLog.stopD(trackKey, "%s contact preload end", trackKey);
        } catch (Exception e) {
            VLog.e(TAG, e);
        }
        VLog.stopD(trackKey, "%s preload end ", trackKey);
        VLog.e("db", "dbinit");
    }

    /**
     * 退出登录时调用这个方法, 所以要想清楚是否要删除相应的表
     */
    void unInitDaos() {
        UserHelper.getUserDBDao().clearCache();
        GroupHelper.getGroupDBDao().clearCache();
        ContactsHelper.getContactsDao().clearCache();
        //暂时放在这里，因为SilentDao不是采用通用的clearCache来实现的
        DaoLoadHelper.silentDaoLoadFinish = false;
    }


    public IDatabaseManager getMainDB() {
        return cocoMainDB;
    }

    public boolean isUserDBReady() {
        return cocoMainDB != null && cocoMainDB.isInited();
    }

}
